package com.lyw.i09assistClass;

import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * 1、信号灯：用于控制对共享资源的访问。它可以用来限制同时访问某个资源的线程数量，提供了一种有效的并发控制机制
 *        Semaphore 是一个计数信号量，用来管理一定数量的许可证。每个线程在访问共享资源之前，需要先获取一
 *        个许可证，如果许可证已经被其他线程占用，则需要等待，直到许可证可用。当线程使用完共享资源后，需要
 *        释放许可证，使其他线程可以继续访问。
 *
 * 2、使用方法
 *    // 其中permits表示许可证的数量，即同一时间内允许的并发访问线程数。
 *    Semaphore semaphore = new Semaphore(int permits);
 *    // 获取许可证
 *    // 如果有可用的许可证，则线程可以继续执行；否则，线程将进入阻塞状态，直到有许可证可用。
 *    semaphore.acquire();
 *    // 释放许可证
 *    // 线程在使用完共享资源后，应该释放许可证，以便其他线程可以获取许可证。
 *    semaphore.release();
 *
 *
 * 应用场景
 *    - 有限资源的并发控制：Semaphore可以限制对有限资源的并发访问，例如数据库连接池或线程池中的资源管理。
 *    - 控制并发线程数：Semaphore可以控制同时执行的线程数量，例如限制同时访问某个接口的请求数量。
 *    - 实现互斥锁：Semaphore可以用于实现互斥锁的功能，通过设置permits为1，保证同一时间只有一个线程可以访问临界区。
 *    - 控制任务流量：Semaphore可以限制任务的执行速率，例如限制某个任务在单位时间内的执行次数。
 *
 * @author lyw
 * @Date 2023/7/10-下午5:21
 */
public class SemaphoreDemo {

  public static void main(String[] args) {
    Semaphore semaphore = new Semaphore(3);
    for (int i = 0; i < 6; i++) {
      new Thread(() -> {
        try {
          System.out.println(Thread.currentThread().getName() + " :抢到车位");
          semaphore.acquire();
          TimeUnit.SECONDS.sleep(new Random().nextInt(5));
          System.out.println(Thread.currentThread().getName() + " ----离开车位");
        } catch (InterruptedException e) {
          e.printStackTrace();
        } finally {
          semaphore.release();
        }
      }, String.valueOf(i)).start();
    }
  }
}
